package com.sunrise.configuracoes.servico;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sunrise.configuracoes.repositorio.iface.FuncionalidadeDao;
import com.sunrise.configuracoes.repositorio.iface.PermissaoDao;
import com.sunrise.crm.repositorio.iface.UsuarioDao;
import com.sunrise.generico.entidade.Funcionalidade;
import com.sunrise.generico.entidade.Permissao;
import com.sunrise.generico.entidade.Usuario;
import com.sunrise.generico.util.MessagesUtil;
import com.sunrise.generico.util.UsuarioLogado;

@Service
public class UsuarioLogadoService implements UserDetailsService {
	
	@Resource(name = "usuarioDaoImpl")
	private UsuarioDao usuarioDao;
	
	@Resource(name = "permissaoDaoImpl")
	private PermissaoDao permissaoDao;
	
	@Resource(name = "funcionalidadeDaoImpl")
	private FuncionalidadeDao funcionalidadeDao;

	@Override
	@Transactional(readOnly = true)
	public UsuarioLogado loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
		Usuario usuario = usuarioDao.buscarPorUsername(username);

		if (usuario == null) {
			throw new UsernameNotFoundException(username);
		}
		
		if(!usuario.getAtivo()){
			throw new DisabledException(MessagesUtil.getMessageKey("AbstractUserDetailsAuthenticationProvider.disabled"));
		}
		
		UsuarioLogado usuarioLogado = new UsuarioLogado();
		usuarioLogado.setAuthorities(carregarPermissoes(usuario.getPerfil().getId()));
		usuarioLogado.setAccountNonExpired(true);
		usuarioLogado.setAccountNonLocked(true);
		usuarioLogado.setCredentialsNonExpired(true);
		usuarioLogado.setEnabled(true);
		usuarioLogado.setPassword(usuario.getPassword());
		usuarioLogado.setUsername(usuario.getUsername());
		usuarioLogado.setNome(usuario.getNome());
		usuarioLogado.setEmail(usuario.getEmail());
	
		return usuarioLogado;
	}

	private List<GrantedAuthorityImpl> carregarPermissoes(Long idPerfil) {
		Collection<Permissao> permissoes = permissaoDao.buscarPorPerfil(idPerfil);
		Collection<Funcionalidade> funcionalidades = funcionalidadeDao.buscarAtivo();
		
		List<GrantedAuthorityImpl> authz = new ArrayList<GrantedAuthorityImpl>();
		for(Permissao permissao : permissoes){
			authz.add(new GrantedAuthorityImpl(permissao.getRole()));
		}
		
		for(Funcionalidade func : funcionalidades){
			authz.add(new GrantedAuthorityImpl(func.getRole()));
		}
		
		
		return authz;
	}

}
